package cn.iocoder.yudao.module.ai.utils;
import cn.iocoder.yudao.module.ai.utils.vo.MaterialFileVo;
import cn.iocoder.yudao.module.ai.utils.vo.UnzipFileVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.nio.file.*;
import java.util.zip.*;

/**
 * 解析文件工具类
 *
 * @author
 * @since 2022/7/12
 */
@SuppressWarnings("unused")
@Slf4j
public class UnZipUtils {

    public static int BYTE_LEN = 10240;

//    /**
//     * 本地文件解压
//     *
//     * @param file 具体文件
//     * @return 解压后的文件列表
//     */
//    public static List<UnzipFileVo> unzip(File file) throws IOException {
//        if (Objects.isNull(file) || !file.exists()) {
//            return Collections.emptyList();
//        }
//        ZipFile zip = null;
//        zip = new ZipFile(file);
//        if (Objects.isNull(zip)) {
//            return Collections.emptyList();
//        }
//        Enumeration<? extends ZipEntry> entries = zip.entries();
//        List<UnzipFileVo> vos = new ArrayList<>();
//        while (entries.hasMoreElements()) {
//            ZipEntry entry = entries.nextElement();
//            String path = entry.getName();
//            UnzipFileVo vo = new UnzipFileVo();
//            vo.setPath(path);
//            // 解析文件夹
//            boolean directory = entry.isDirectory();
//            if (directory) {
//                vo.setType(0);
//                vos.add(vo);
//                continue;
//            }
//            // 解析文件
//            vo.setType(1);
//            StringBuilder sb = new StringBuilder();
//            try (InputStream in = zip.getInputStream(entry);
//                 InputStreamReader inputStreamReader = new InputStreamReader(in);
//                 BufferedReader reader = new BufferedReader(inputStreamReader)) {
//                String line;
//                while ((line = reader.readLine()) != null) {
//                    sb.append(line).append("\n");
//                }
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//            vo.setContent(sb.toString());
//            vos.add(vo);
//        }
//        if (Objects.nonNull(zip)) {
//            try {
//                zip.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//        return vos;
//    }
//
//
//    /**
//     * 上传文件解压
//     *
//     * @param multipartFile 上传文件
//     * @return 解压后的文件列表
//     */
//    public static List<UnzipFileVo> unzip(MultipartFile multipartFile) throws IOException {
//        File file = getFile(multipartFile);
//        if (Objects.isNull(file)) {
//            return Collections.emptyList();
//        }
//        List<UnzipFileVo> vos = unzip(file);
//        if (file.exists()) {
//            boolean delete = file.delete();
//            if (delete) {
//                System.out.println(file.getName() + " 临时文件删除成功！");
//            } else {
//                System.out.println(file.getName() + " 临时文件删除失败！");
//            }
//        }
//        return vos;
//    }
//
//    /**
//     * MultipartFile 转 File
//     *
//     * @param multipartFile 上传文件
//     * @return 本地文件
//     */
//    private static File getFile(MultipartFile multipartFile) {
//        String fileName = System.currentTimeMillis() + "_" + multipartFile.getOriginalFilename();
//        File file = new File("D://" + fileName);
//        int len;
//        try (OutputStream os = new FileOutputStream(file);
//             InputStream in = multipartFile.getInputStream()) {
//            byte[] buffer = new byte[BYTE_LEN];
//            while ((len = in.read(buffer, 0, BYTE_LEN)) != -1) {
//                os.write(buffer, 0, len);
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//            return null;
//        }
//        return file;
//    }


    /**
     * 文件解压缩
     * @return
     */
    public static List<MaterialFileVo> fileUncompressing(String zipFilePath, String targetFolder) throws IOException{
        //返回消息
        List<MaterialFileVo> fileList=new ArrayList<>();
        // 解压文件索引
        int fileIndex = 0;
        // 打开压缩文件
        File sourceFile = new File(zipFilePath);
        ZipFile zipFile = new ZipFile(sourceFile.getAbsoluteFile(), Charset.forName("gbk"));

        // 遍历压缩文件中的所有条目
        Enumeration<? extends ZipEntry> entries = zipFile.entries();
        while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();

            // 解压缩条目到目标文件夹
            String entryName = entry.getName();
            entryName = new String(entryName.getBytes(StandardCharsets.UTF_8));
            // 扩展名
            String extension = FilenameUtils.getExtension(entryName);
            if (entry.isDirectory()) {
                //entryFile.mkdirs();
            } else {
                // 重新整理写到新的文件路径
                String newFileName = (++fileIndex)+"."+extension;
                File targetFile = new File(targetFolder+"/"+newFileName);
                InputStream inputStream = zipFile.getInputStream(entry);
                OutputStream outputStream = new FileOutputStream(targetFile);
                byte[] buffer = new byte[1024];
                int length;
                while ((length = inputStream.read(buffer)) > 0) {
                    outputStream.write(buffer, 0, length);
                }
                outputStream.flush();
                outputStream.close();
                inputStream.close();
                MaterialFileVo e = new MaterialFileVo();
                e.setFile(targetFile);
                e.setOriginalFileName(entryName);
                e.setOriginalFilePath(entry.getName());
                e.setFileName(newFileName);
                fileList.add(e);
            }
        }
        // 关闭压缩文件
        zipFile.close();
        return fileList;
    }

//    /**
//     * 获取视频播放时长
//     * @param filePath
//     * @return
//     */
//    public static Integer getMp4Seconds(String filePath){
//        int seconds = 0;
//        FFmpegFrameGrabber grabber = null;
//        try {
//            grabber = new FFmpegFrameGrabber(filePath);
//            grabber.start();
//            //这一步获取的是微妙，除以 1000000 获取保留整数部位的秒
//            seconds = Math.toIntExact(grabber.getLengthInTime())/1000000;
//            log.info("视频文件"+filePath+"Duration of the MP4 file: " + seconds + " s");
//            return seconds; // 返回秒
//        } catch (Exception e) {
//            log.warn("读取文件播放时长失败:"+filePath,e);
//            return 0;
//        } finally {
//            if (grabber != null) {
//                try {
//                    grabber.stop();
//                } catch (Exception ignored) {
//                }
//            }
//        }
//    }
//
//    public static void main(String[] args) {
//        System.out.println(getMp4Seconds("D:\\data\\material\\2024\\12\\20241226183615211\\release\\1.mp4"));
//    }

    // 解压 ZIP 文件到指定目录
    public static void unzip(String zipFilePath, Path destDir) throws IOException {
        try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFilePath))) {
            ZipEntry zipEntry = zis.getNextEntry();
            while (zipEntry != null) {
                Path newFile = destDir.resolve(zipEntry.getName());
                if (zipEntry.isDirectory()) {
                    Files.createDirectories(newFile);
                } else {
                    // 确保父目录存在
                    Files.createDirectories(newFile.getParent());
                    try (BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(newFile))) {
                        byte[] bytesIn = new byte[4096];
                        int read;
                        while ((read = zis.read(bytesIn)) != -1) {
                            bos.write(bytesIn, 0, read);
                        }
                    }
                }
                zipEntry = zis.getNextEntry();
            }
            zis.closeEntry();
        }
    }

    // 压缩指定目录到 ZIP 文件
    public static String zipDirectory(String sourceDirPath, String zipFilePath) throws IOException {
        Path sourceDir = Paths.get(sourceDirPath);
        try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFilePath))) {
            Files.walkFileTree(sourceDir, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    ZipEntry zipEntry = new ZipEntry(sourceDir.relativize(file).toString());
                    zos.putNextEntry(zipEntry);
                    Files.copy(file, zos);
                    zos.closeEntry();
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                    ZipEntry zipEntry = new ZipEntry(sourceDir.relativize(dir).toString() + "/");
                    zos.putNextEntry(zipEntry);
                    zos.closeEntry();
                    return FileVisitResult.CONTINUE;
                }
            });
        }
        return zipFilePath.toString();
    }

}